<template>
  <div class="table-app-container">
    <div class="fixed-table" style="border: 0;">
      <div class="fixed-table-actionbar">
        <div class="action-bar">
          <el-button type="primary" size="mini" icon="el-icon-plus" @click="onOpenEditRelation('')">添加关联</el-button>
        </div>
      </div>
      <PageableTable
        :loading="loading"
        :data="insideTableData"
        :total="0"
        :table-height="tableHeight"
        :disable-pageable="true"
        class="fixed-table-table"
      >
        <el-table-column v-for="column in insideColumns" :key="column.key" :width="column.width" :label="column.title" :prop="column.key" :sortable="column.sortable">
          <template slot-scope="scope">
            <column-render :render="column.render" :row="scope.row" :column="column" />
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="120" class-name="small-padding fixed-width">
          <template slot-scope="{row}">
            <el-button title="编辑" type="text" size="mini" icon="el-icon-edit" @click="onOpenEditRelation(row)" />
            <el-button title="删除" type="text" size="mini" icon="el-icon-delete" @click="remove(row._id)" />
          </template>
        </el-table-column>
      </PageableTable>
    </div>
    <FormDialog title="添加关联" :show.sync="addRelaDialogVisible" width="50%" :drawer="true" @on-ok="onAddRelationOk" @on-cancel="onAddRelationCancel">
      <el-form ref="addform" :model="addFormItem" label-width="100px" size="mini" class="attr-form">
        <input v-model="addFormItem._id" type="hidden">
        <el-form-item
          label="描述"
          prop="desc"
          required
          :rules="{required: true, message: '描述不能为空', trigger: 'blur'}"
        >
          <el-input v-model="addFormItem.desc" />
        </el-form-item>
        <el-form-item
          label="关联关系"
          prop="rela"
          required
          :rules="{required: true, message: '关联关系不能为空', trigger: 'blur'}"
        >
          <el-select v-model="addFormItem.rela" :disabled="!!addFormItem._id" filterable placeholder="关联关系" @change="onRelationChange">
            <el-option v-for="item in availableRelations" :key="item._id" :label="item.desc" :value="item._id" />
          </el-select>
        </el-form-item>
        <el-form-item
          label="源实例"
          prop="src"
          required
          :rules="{ required: true, message: '源实例不能为空', trigger: 'blur' }"
        >
          <el-select v-model="addFormItem.src" :disabled="!!addFormItem._id" filterable placeholder="源实例">
            <el-option v-for="item in availableSrcInstances" :key="item._id" :label="item.name" :value="item._id" />
          </el-select>
        </el-form-item>
        <el-form-item
          label="目标实例"
          prop="dest"
          required
          :rules="{ required: true, message: '目标实例不能为空', trigger: 'blur' }"
        >
          <el-select v-model="addFormItem.dest" :disabled="!!addFormItem._id" filterable placeholder="目标实例">
            <el-option v-for="item in availableDestInstances" :key="item._id" :label="item.name" :value="item._id" />
          </el-select>
        </el-form-item>
        <el-form-item v-for="(attr, idx) in addFormItem.attrs" :key="attr.field" :label="attr.name" :prop="'attrs.' + idx + '.' + attr.field">
          <number-input v-if="attr.dtype==='number'" v-model="attr.val" />
          <bool-checkbox v-else-if="attr.dtype==='bool'" v-model="attr.val" />
          <date-input v-else-if="attr.dtype==='date'" v-model="attr.val" />
          <string-input v-else v-model="attr.val" :maxlen="attr.len" />
        </el-form-item>
      </el-form>
    </FormDialog>
  </div>
</template>

<script>
import FormDialog from '@neu/biz-core/components/FormDialog'
import PageableTable from '@neu/biz-core/components/PageableTable'
import databind from '@neu/biz-core/mixins/databind'
import { debounce } from '@neu/biz-core/utils'
import { on } from '@neu/biz-core/utils/utils'
import { detail as instanceDetail, getRelations, listBySchema, addRelation, removeRelation } from '@neu/cmdb-ui/api/instance'
import { update as relationInstanceUpdate } from '@neu/cmdb-ui/api/relationinstance'
import { getRelations as getSchemaRelatins } from '@neu/cmdb-ui/api/schema'

export default {
  name: 'InstanceRelationComponent',
  components: {
    FormDialog,
    PageableTable
  },
  mixins: [databind],
  props: {
    instanceId: {
      required: true,
      type: String
    }
  },
  data() {
    return {
      instance: {},
      // 可用的关系（与模型定义有关）
      availableRelations: [],
      // 可选的目标实例（与关联关系的目标模型设置有关）
      availableSrcInstances: [],
      availableDestInstances: [],
      addRelaDialogVisible: false,
      r: getRelations(this.instanceId),
      d: removeRelation(this.instanceId),
      insideColumns: [
        { title: '描述', key: 'desc' },
        {
          title: '源实例',
          key: 'src.name',
          render: (h, params) => {
            return (
              <router-link to={'/cmdb/instances/' + params.row.src._id} class={'el-link el-link--primary'}>{ params.row.src.name }</router-link>
            )
          }
        },
        {
          title: '目标实例',
          key: 'dest.name',
          render: (h, params) => {
            return (
              <router-link to={'/cmdb/instances/' + params.row.dest._id} class={'el-link el-link--primary'}>{ params.row.dest.name }</router-link>
            )
          }
        },
        {
          title: '所属关联',
          key: 'rela.desc',
          render: (h, params) => {
            return (
              h('span', params.row.rela.desc)
            )
          }
        }
      ],
      addFormItem: {
        desc: '',
        src: '',
        dest: '',
        rela: '',
        attrs: []
      }
    }
  },
  created() {
    instanceDetail(this.instanceId).then(response => {
      this.instance = response.data
      getSchemaRelatins(this.instance.schemadef._id)().then(response1 => {
        this.availableRelations = response1.data
      })
    })
    this.filter()
  },
  methods: {
    onOpenEditRelation: async function(relationInstance) {
      if (relationInstance) {
        const srcSchemaId = relationInstance.rela.src
        if (this.instance.schemadef._id === srcSchemaId) {
          this.availableSrcInstances = [this.instance]
          this.addFormItem.src = this.instanceId
          this.availableDestInstances = [relationInstance.dest]
          this.addFormItem.dest = relationInstance.dest._id
        } else {
          this.availableSrcInstances = [relationInstance.src]
          this.addFormItem.src = relationInstance.src._id
          this.availableDestInstances = [this.instance]
          this.addFormItem.dest = this.instanceId
        }

        this.addFormItem._id = relationInstance._id
        this.addFormItem.desc = relationInstance.desc
        this.addFormItem.rela = relationInstance.rela._id

        this.addFormItem.attrs = []
        const mAttrs = relationInstance.rela.attrs.map(it => {
          const attrItem = relationInstance.attrs && relationInstance.attrs.find(a => a.key === it.field)
          return {
            field: it.field,
            name: it.name,
            val: attrItem ? attrItem.value : '',
            dtype: it.dtype,
            notnullable: it.notnullable,
            len: it.len
          }
        })
        this.addFormItem.attrs = mAttrs
        this.addRelaDialogVisible = true
      } else {
        const data = {
          src: '',
          dest: '',
          desc: '',
          rela: '',
          attrs: []
        }
        this.addFormItem = { ...data }
        this.addRelaDialogVisible = true
      }
    },
    onAddRelationOk() {
      const { desc, src, dest, rela, attrs } = this.addFormItem
      const data = { desc, src, dest, rela, attrs: {}}
      attrs.forEach(a => {
        data.attrs[a.field] = a.val
      })

      this.$refs.addform.validate(valid => {
        if (valid) {
          if (this.addFormItem._id) {
            relationInstanceUpdate(this.addFormItem._id, data).then(response => {
              this.addRelaDialogVisible = false
              this.filter()
            })
          } else {
            addRelation(this.instanceId, data).then(response => {
              this.addRelaDialogVisible = false
              this.filter()
            })
          }
        }
      })
    },
    onAddRelationCancel() {
      this.addRelaDialogVisible = false
    },
    onRelationChange(relationId) {
      const relation = this.availableRelations.find(it => it._id === relationId)
      const srcSchemaId = relation.src._id
      if (this.instance.schemadef._id === srcSchemaId) {
        this.availableSrcInstances = [this.instance]
        this.addFormItem.src = this.instanceId
        listBySchema(relation.dest._id).then(response => {
          this.availableDestInstances = response.data
        })
      } else {
        this.availableDestInstances = [this.instance]
        this.addFormItem.dest = this.instanceId
        listBySchema(relation.src._id).then(response => {
          this.availableSrcInstances = response.data
        })
      }
      this.addFormItem.attrs = []
      var attrs = relation.attrs.map(it => {
        return {
          field: it.field,
          name: it.name,
          val: '',
          dtype: it.dtype,
          notnullable: it.notnullable,
          len: it.len
        }
      })
      this.addFormItem.attrs.push(...attrs)
    },
    initListener() {
      this.$_resizeHandler = debounce(() => {
        const _this = this
        // 页面头高度 50
        // .app-container padding上下总和 16
        // document.querySelector('.table-app-container .fixed-table-filter').offsetHeight
        // document.querySelector('.table-app-container .fixed-table-actionbar')
        // 翻页组件高度 42
        // .fixed-table padding上下和边框 18
        const baseInfoSel = document.querySelector('.app-container .instance-edit-container .base-info')
        const baseInfoHeight = baseInfoSel ? baseInfoSel.offsetHeight : 0

        const tabsSel = document.querySelector('.el-tabs__header')
        const tabsHeight = tabsSel ? tabsSel.offsetHeight + 15 : 0

        const tableFilterSel = document.querySelector('.table-app-container .fixed-table-filter')
        const tableFilterHeight = tableFilterSel ? tableFilterSel.offsetHeight : 0

        const tableActionbarSel = document.querySelector('.table-app-container .fixed-table-actionbar')
        const tableActionbarHeight = tableActionbarSel ? tableActionbarSel.offsetHeight : 0

        const assetTableBarSel = document.querySelector('.table-app-container .asset-table-bar')
        const assetTableBarHeight = assetTableBarSel ? assetTableBarSel.offsetHeight : 0

        const filterTreeSel = document.querySelector('.table-app-container .filter-tree')
        if (filterTreeSel) {
          filterTreeSel.style.height = (window.innerHeight - 50 - 16) + 'px'
        }

        _this.tableHeight = window.innerHeight - 50 - 16 - baseInfoHeight - tabsHeight - tableFilterHeight - assetTableBarHeight - tableActionbarHeight - 22
      }, 300)

      on(window, 'resize', this.$_resizeHandler)
    }
  }
}
</script>
